package com.ruoyi.dynamic.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.pojo.result.PageUtils;
import com.ruoyi.common.core.pojo.result.Pages;
import com.ruoyi.common.core.utils.CollectionUtils;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.cache.CacheTemplate;
import com.ruoyi.dynamic.mapper.RoomVoteMusicMapper;
import com.ruoyi.dynamic.model.constant.DynamicConstant;
import com.ruoyi.dynamic.model.constant.RoomChatRoomKvConstant;
import com.ruoyi.dynamic.model.pojo.entity.*;
import com.ruoyi.dynamic.model.pojo.request.app.*;
import com.ruoyi.dynamic.model.pojo.result.app.AppRoomVoteMusicResult;
import com.ruoyi.dynamic.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Gnc
 * @since 2025-01-04
 */
@Service
public class RoomVoteMusicServiceImpl extends ServiceImpl<RoomVoteMusicMapper, RoomVoteMusic> implements IRoomVoteMusicService {


    @Autowired
    private IRoomService iRoomService;
    @Autowired
    private IRoomVoteMusicResourceService iRoomVoteMusicResourceService;
    @Autowired
    private IMessageService iMessageService;
    @Autowired
    private IRoomVoteMusicRecordService iRoomVoteMusicRecordService;


    @Override
    public boolean create(Long userId, AppRoomVoteMusicAddRequest request) {
        Room verify = iRoomService.verify(request.getRoomId());
        Assert.isTrue(verify.getUserId().equals(userId), "只有主持才可以发布投票");

        if (request.getIsTemplate().equals(DynamicConstant.CheckStatus.NO)) {
            Long count = lambdaQuery()
                    .ne(!CommonUtils.isNull(request.getId()), RoomVoteMusic::getId, request.getId())
                    .eq(RoomVoteMusic::getRoomId, request.getRoomId())
                    .eq(RoomVoteMusic::getStatus, DynamicConstant.CheckStatus.YES)
                    .count();
            Assert.isTrue(count == 0, "还有未结束的投票场次无法发起");
        }


        RoomVoteMusic roomVoteMusic = getById(request.getId());
        if (CommonUtils.isNull(roomVoteMusic)) {
            roomVoteMusic = new RoomVoteMusic();
        }
        roomVoteMusic.setRoomId(request.getRoomId());
        if (request.getIsTemplate().equals(DynamicConstant.CheckStatus.YES)) {
            roomVoteMusic.setFromId(1L);
            roomVoteMusic.setRoomId(0L);
        }
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        instance.add(Calendar.SECOND, +request.getVoteTime());
        roomVoteMusic.setId(null);
        roomVoteMusic.setTitle(request.getTitle());
        roomVoteMusic.setUserId(userId);
        roomVoteMusic.setCreateTime(new Date());
        roomVoteMusic.setVoteTime(request.getVoteTime());
        roomVoteMusic.setStatus(DynamicConstant.CheckStatus.YES);
        roomVoteMusic.setEndTime(instance.getTime());
        roomVoteMusic.setIsTemplate(request.getIsTemplate());
        if (save(roomVoteMusic)) {
            //发送redis过期事件
            CacheTemplate.setCacheExpire(RoomChatRoomKvConstant.ROOM_VOTE_MUSIC + roomVoteMusic.getId(), roomVoteMusic.getId(), Long.valueOf(roomVoteMusic.getVoteTime()), TimeUnit.SECONDS);

            Long id = roomVoteMusic.getId();
            iRoomVoteMusicResourceService.lambdaUpdate()
                    .eq(RoomVoteMusicResource::getVoteMusicId, id)
                    .remove();

            List<RoomVoteMusicResource> collect = request.getResourceAddRequests().stream().map(res -> {
                RoomVoteMusicResource resource = new RoomVoteMusicResource();
                resource.setGiftId(res.getGiftId());
                resource.setGiftImg(res.getGiftImg());
                resource.setGiftNum(res.getGiftNum());
                resource.setName(res.getName());
                resource.setRoomId(request.getRoomId());
                resource.setVoteMusicId(id);
                resource.setVoteTime(request.getVoteTime());
                resource.setCreateTime(new Date());
                resource.setRatio("0%");
                return resource;
            }).collect(Collectors.toList());
            iRoomVoteMusicResourceService.saveBatch(collect);

            if (request.getIsTemplate().equals(DynamicConstant.CheckStatus.NO)) {
                AppRoomVoteMusicResult build = AppRoomVoteMusicResult.builder()
                        .id(roomVoteMusic.getId())
                        .resources(collect)
                        .roomId(verify.getId())
                        .status(roomVoteMusic.getStatus())
                        .title(roomVoteMusic.getTitle())
                        .userId(roomVoteMusic.getUserId())
                        .voteTime(roomVoteMusic.getVoteTime())
                        .build();

                iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(),
                        RoomChatRoomKvConstant.ROOM_VOTE_MUSIC_INFO, JSONObject.toJSONString(build), 0, "", "");
            }
        }
        return true;
    }

    @Override
    public Pages<AppRoomVoteMusicResult> listPage(AppRoomVoteSearchRequest request, Long userId) {
        Page<RoomVoteMusic> roomVoteMusicPage = PageUtils.initPage(request, RoomVoteMusic.class);

        Page<RoomVoteMusic> page = lambdaQuery()
                .eq(!CommonUtils.isNull(request.getRoomId()), RoomVoteMusic::getRoomId, request.getRoomId())
                .eq(request.isTemplate(), RoomVoteMusic::getUserId, userId)
                .eq(request.isTemplate(), RoomVoteMusic::getIsTemplate, DynamicConstant.CheckStatus.YES)
                .orderByDesc(RoomVoteMusic::getCreateTime)
                .page(roomVoteMusicPage);

        List<AppRoomVoteMusicResult> results = CollectionUtils.emptyList();
        for (RoomVoteMusic record : page.getRecords()) {
            results.add(getInfo(record, userId));
        }
        return PageUtils.pages(page, results);
    }

    @Override
    public AppRoomVoteMusicResult info(Long id, Long userId) {
        RoomVoteMusic verify = verify(id);
        return getInfo(verify, userId);
    }

    @Override
    public AppRoomVoteMusicResult getInfo(RoomVoteMusic record, Long userId) {
        Long count = iRoomVoteMusicRecordService.lambdaQuery()
                .eq(RoomVoteMusicRecord::getUserId, userId)
                .eq(RoomVoteMusicRecord::getVoteMusicId, record.getId())
                .count();
        return AppRoomVoteMusicResult.builder()
                .id(record.getId())
                .resources(getRoomVoteMusicListNotDesc(record.getRoomId(), record.getId(), userId))
                .roomId(record.getId())
                .status(record.getStatus())
                .title(record.getTitle())
                .userId(record.getUserId())
                .residueTime(DateUtils.timeBySec(record.getEndTime(), new Date()))
                .voteTime(record.getVoteTime())
                .isTemplate(record.getIsTemplate())
                .isVote(count > 0)
                .fromId(record.getFromId())
                .build();
    }

    @Override
    public RoomVoteMusic verify(Long id) {
        RoomVoteMusic byId = getById(id);
        Assert.notNull(byId, "此投票详情不存在");
        return byId;
    }

    @Override
    public boolean over(AppRoomVoteMusicOverRequest request, Long userId) {
        this.voteOver(request.getId().toString(), DynamicConstant.CheckStatus.START);
        return true;
    }

    @Override
    public boolean start(AppRoomVoteMusicStartRequest request, Long userId) {
        Room verify = iRoomService.verify(request.getRoomId());
        RoomVoteMusic voteMusic = verify(request.getId());
        Assert.isTrue(voteMusic.getStatus().equals(DynamicConstant.CheckStatus.YES), "该投票场次未开始/已结束无法结束");

        RoomVoteMusicResource resource = iRoomVoteMusicResourceService.getById(request.getResourceId());
        Assert.notNull(resource, "歌曲资源不存在");

        Long count = iRoomVoteMusicRecordService.lambdaQuery()
                .eq(RoomVoteMusicRecord::getRoomId, request.getRoomId())
                .eq(RoomVoteMusicRecord::getVoteMusicId, request.getId())
                .eq(RoomVoteMusicRecord::getUserId, userId)
                .count();
        Assert.isTrue(count == 0, "您已投票过 请勿重复投票");
        resource.setVoteNum(resource.getVoteNum() + 1);
        if (iRoomVoteMusicResourceService.updateById(resource)) {
            iRoomVoteMusicRecordService.addRecord(verify.getId(), request.getId(), request.getResourceId(), userId);
        }

        AppRoomVoteMusicResult build = AppRoomVoteMusicResult.builder()
                .id(voteMusic.getId())
                .resources(getRoomVoteMusicListNotDesc(verify.getId(), voteMusic.getId(), userId))
                .roomId(verify.getId())
                .status(voteMusic.getStatus())
                .title(voteMusic.getTitle())
                .userId(voteMusic.getUserId())
                .voteTime(voteMusic.getVoteTime())
                .build();

        iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(),
                RoomChatRoomKvConstant.ROOM_VOTE_MUSIC_INFO, JSONObject.toJSONString(build), 0, "", "");
        return true;
    }

    @Override
    public boolean saveTem(Long id, Long userId) {
        RoomVoteMusic verify = verify(id);
        verify.setIsTemplate(DynamicConstant.CheckStatus.YES);
        verify.setFromId(verify.getId());
        verify.setUserId(userId);
        return updateById(verify);
    }

    public List<RoomVoteMusicResource> getRoomVoteMusicListNotDesc(Long roomId, Long voteMusicId, Long userId) {
        List<RoomVoteMusicResource> list = iRoomVoteMusicResourceService.lambdaQuery()
                .eq(RoomVoteMusicResource::getVoteMusicId, voteMusicId)
                .list();
        int sum = list.stream().mapToInt(RoomVoteMusicResource::getVoteNum).sum();
        for (RoomVoteMusicResource resource : list) {
            resource.setRatio(CommonUtils.isGetRatioByTotal(sum, resource.getVoteNum()));
            resource.setVote(isVoteByUser(userId, resource.getId()));
        }
        return list;
    }

    public boolean isVoteByUser(Long userId, Long id) {
        return iRoomVoteMusicRecordService.lambdaQuery().eq(RoomVoteMusicRecord::getUserId, userId)
                .eq(RoomVoteMusicRecord::getResourceId, id).count() > 0;
    }


    @Override
    public List<RoomVoteMusicResource> getRoomVoteMusicList(Long roomId, Long voteMusicId) {
        List<RoomVoteMusicResource> list = iRoomVoteMusicResourceService.lambdaQuery()
                .eq(RoomVoteMusicResource::getVoteMusicId, voteMusicId)
                .orderByDesc(RoomVoteMusicResource::getVoteNum)
                .list();
        int sum = list.stream().mapToInt(RoomVoteMusicResource::getVoteNum).sum();
        for (RoomVoteMusicResource resource : list) {
            resource.setRatio(CommonUtils.isGetRatioByTotal(sum, resource.getVoteNum()));
        }
        return list;
    }

    @Override
    public void voteOver(String id, Integer status) {
        RoomVoteMusic music = verify(Long.valueOf(id));
        Room verify = iRoomService.verify(music.getRoomId());
        if (status.equals(DynamicConstant.CheckStatus.FENG) && music.getStatus().equals(DynamicConstant.CheckStatus.YES)) {
            //第一个结束
            Calendar instance = Calendar.getInstance();
            instance.setTime(music.getEndTime());
            instance.add(Calendar.SECOND, 60);
            music.setStatus(status);
            music.setEndTime(instance.getTime());
            //发送redis过期事件
            CacheTemplate.setCacheExpire(RoomChatRoomKvConstant.ROOM_VOTE_MUSIC_END + music.getId(), music.getId(), 60L, TimeUnit.SECONDS);
        } else if (status.equals(DynamicConstant.CheckStatus.START)) {
            //第二个1分钟结束
            music.setStatus(status);
            CacheTemplate.clear(RoomChatRoomKvConstant.ROOM_VOTE_MUSIC_END + music.getId());
            CacheTemplate.clear(RoomChatRoomKvConstant.ROOM_VOTE_MUSIC + music.getId());
        }
        updateById(music);

        AppRoomVoteMusicResult build = AppRoomVoteMusicResult.builder()
                .id(music.getId())
                .roomId(verify.getId())
                .status(music.getStatus())
                .title(music.getTitle())
                .userId(music.getUserId())
                .voteTime(music.getVoteTime())
                .resources(getRoomVoteMusicListNotDesc(music.getRoomId(), music.getId(), 0L))
                .build();

        iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(),
                RoomChatRoomKvConstant.ROOM_VOTE_MUSIC_INFO, JSONObject.toJSONString(build), 0, "", "");
    }


    @Override
    public boolean templateCreate(Long userId, AppRoomVoteMusicTemRequest request) {
        RoomVoteMusic music = verify(request.getId());
        Room verify = iRoomService.verify(request.getRoomId());
        Assert.isTrue(verify.getUserId().equals(userId), "只有主播才能操作");

        Long count = lambdaQuery()
                .ne(!CommonUtils.isNull(request.getId()), RoomVoteMusic::getId, music.getId())
                .eq(RoomVoteMusic::getRoomId, request.getRoomId())
                .in(RoomVoteMusic::getStatus, DynamicConstant.CheckStatus.YES, DynamicConstant.CheckStatus.FENG)
                .count();
        Assert.isTrue(count == 0, "还有未结束的投票场次无法发起");


        List<RoomVoteMusicResource> list = iRoomVoteMusicResourceService.lambdaQuery().eq(RoomVoteMusicResource::getVoteMusicId, music.getId()).list();

        RoomVoteMusic voteMusic = new RoomVoteMusic();
        BeanUtils.copyProperties(music, voteMusic);
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        instance.add(Calendar.SECOND, voteMusic.getVoteTime());
        voteMusic.setEndTime(instance.getTime());
        voteMusic.setId(null);
        voteMusic.setStatus(DynamicConstant.CheckStatus.YES);
        voteMusic.setIsTemplate(DynamicConstant.CheckStatus.NO);
        voteMusic.setCreateTime(new Date());
        voteMusic.setRoomId(request.getRoomId());
        voteMusic.setFromId(music.getId());
        if (save(voteMusic)) {


            List<RoomVoteMusicResource> collect = list.stream().map(res -> {
                RoomVoteMusicResource resource = new RoomVoteMusicResource();
                BeanUtils.copyProperties(res, resource);
                resource.setId(null);
                resource.setRoomId(request.getRoomId());
                resource.setVoteMusicId(voteMusic.getId());
                resource.setRatio("0%");
                return resource;
            }).collect(Collectors.toList());
            iRoomVoteMusicResourceService.saveBatch(collect);


            AppRoomVoteMusicResult build = AppRoomVoteMusicResult.builder()
                    .id(voteMusic.getId())
                    .resources(collect)
                    .roomId(verify.getId())
                    .status(voteMusic.getStatus())
                    .title(voteMusic.getTitle())
                    .userId(voteMusic.getUserId())
                    .voteTime(voteMusic.getVoteTime())
                    .build();

            //发送redis过期事件
            CacheTemplate.setCacheExpire(RoomChatRoomKvConstant.ROOM_VOTE_MUSIC + voteMusic.getId(), voteMusic.getId(), Long.valueOf(voteMusic.getVoteTime()), TimeUnit.SECONDS);

            iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(),
                    RoomChatRoomKvConstant.ROOM_VOTE_MUSIC_INFO, JSONObject.toJSONString(build), 0, "", "");

        }
        return true;
    }

    @Override
    public boolean removeTem(Long id) {
        verify(id);
        return lambdaUpdate()
                .eq(RoomVoteMusic::getId, id)
                .set(RoomVoteMusic::getIsTemplate, DynamicConstant.CheckStatus.NO)
                .update();
    }

    @Override
    public boolean updateTem(Long userId, AppRoomVoteMusicUpdateRequest request) {
        RoomVoteMusic verify = verify(request.getId());
        verify.setVoteTime(request.getVoteTime());
        verify.setTitle(request.getTitle());
        verify.setIsTemplate(DynamicConstant.CheckStatus.YES);
        updateById(verify);

        iRoomVoteMusicResourceService.lambdaUpdate().eq(RoomVoteMusicResource::getVoteMusicId, request.getId()).remove();

        List<RoomVoteMusicResource> collect = request.getResourceAddRequests().stream().map(res -> {
            RoomVoteMusicResource resource = new RoomVoteMusicResource();
            resource.setGiftId(res.getGiftId());
            resource.setGiftImg(res.getGiftImg());
            resource.setGiftNum(res.getGiftNum());
            resource.setName(res.getName());
            resource.setVoteMusicId(verify.getId());
            resource.setVoteTime(request.getVoteTime());
            resource.setCreateTime(new Date());
            return resource;
        }).collect(Collectors.toList());
        iRoomVoteMusicResourceService.saveBatch(collect);

        return true;
    }

}
